package cave.ui;

import java.util.ArrayList;
import cave.game.InputEvent;
import cave.renderer.RenderList;
import cave.renderer.Sprite;
import cave.renderer.Texture;
import cave.utils.Pool;


public class Button implements DynamicUiItem {
	
	private ButtonListener listener;
	private float width, height;
	private float x, y;
	private Sprite sprUp, sprPressed, sprDisabled;
	private State state;
	private boolean click;
	private int pointerId;
	
	private enum State {
		UP,
		PRESSED,
		DISABLED
	}
	
	public Button(float x, float y, float width, float height, Texture texUp,
			Texture texDown, Texture texDisabled, ButtonListener listener) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.width = width;
		this.listener = listener;
		pointerId = -1;
		state = State.UP;
		sprUp = Pool.getSprite();
		sprUp.init(texUp, x, y, width, height);
		sprPressed = Pool.getSprite();
		sprPressed.init(texDown, x, y, width, height);
		sprDisabled = Pool.getSprite();
		sprDisabled.init(texDisabled, x, y, width, height);
		
	}

	@Override
	public void update(float dt, ArrayList<InputEvent> events) {
		if (state != State.DISABLED) {
			InputEvent event;
			for (int i = 0; i < events.size(); i++) {
				event = events.get(i);
				if (!event.isInUse()) {
					
					switch (event.getType()) {
					case UP:
						if (state == State.PRESSED && pointerId == event.getPointerId() &&
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height) {
							event.setInUse(true);
							state = State.UP;
							pointerId = -1;
							listener.actionUp();
							if (click) {
								listener.actionClick();
							}
						}
						break;
					case DOWN:
						if (state == State.UP &&
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height) {
							pointerId = event.getPointerId();
							event.setInUse(true);
							state = State.PRESSED;
							listener.actionDown();
							click = true;
						}
						break;
					case MOVE:
						if (state == State.PRESSED && pointerId == event.getPointerId() && !(
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height)) {
							click = false;
							state = State.UP;
							pointerId = -1;
							listener.actionUp();
						} else if (state == State.UP &&
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height) {
							pointerId = event.getPointerId();
							event.setInUse(true);
							click = false;
							state = State.PRESSED;
							listener.actionDown();
						}
						break;
					}
				}
			}
		}
	}

	@Override
	public void draw(RenderList renderList) {
		switch (state) {
			case UP:
				renderList.addScreenSprite(sprUp);
				break;
			case PRESSED:
				renderList.addScreenSprite(sprPressed);
				break;
			case DISABLED:
				renderList.addScreenSprite(sprDisabled);
				break;
		}
	}
	
	public void setEnabled(boolean isEnabled) {
		if (isEnabled) {
			state = State.UP;
		} else {
			state = State.DISABLED;
		}
	}
	
	public boolean isEnabled() {
		if (state != State.DISABLED) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean isDown() {
		if (state == State.PRESSED) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean isUp() {
		if (state == State.UP) {
			return true;
		} else {
			return false;
		}
	}
	
	public void destroy() {
		sprUp.freeTextures();
		sprPressed.freeTextures();
		sprDisabled.freeTextures();
		Pool.free(sprUp);
		Pool.free(sprPressed);
		Pool.free(sprDisabled);
	}
	
}
